﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Shared
{
    public class NetworkHandler
    {
        #region Fields

        /// <summary>
        /// Listens for connection requests.
        /// </summary>
        public TcpListener Listener;

        /// <summary>
        /// Specifies if the listener is listening or not.
        /// </summary>
        private bool IsListening = false;

        /// <summary>
        /// Queue list size for the listener.
        /// </summary>
        private const int QueueListSize = 5;

        /// <summary>
        /// Callback for connection handling.
        /// </summary>
        private AsyncCallback Callback;

        #endregion

        #region Constructor

        /// <summary>
        /// Constructs a new network handler.
        /// </summary>
        /// <param name="Ip">IP Address to listen on.</param>
        /// <param name="Port">Port to listen on.</param>
        /// <param name="Callback">Callback to the program's connection handling function.</param>
        public NetworkHandler(string Ip, int Port, AsyncCallback Callback)
        {
            IPAddress BoundIP;

            if (Ip == "Any")
            {
                BoundIP = IPAddress.Any;
            }
            else if (!IPAddress.TryParse(Ip, out BoundIP))
            {
                BoundIP = IPAddress.Loopback;
            }

            this.Callback = Callback;
            this.Listener = new TcpListener(BoundIP, Port);
        }

        #endregion

        #region Methods

        /// <summary>
        /// Starts listening for client connections.
        /// </summary>
        public void Start()
        {
            if (this.IsListening)
            {
                return;
            }

            this.Listener.Start(NetworkHandler.QueueListSize);
            this.IsListening = true;

            this.Standby();
        }

        /// <summary>
        /// Stops listening.
        /// </summary>
        public void Stop()
        {
            if (!this.IsListening)
            {
                return;
            }

            this.Listener.Stop();
            this.IsListening = false;
        }

        /// <summary>
        /// Stands by to receive a new connection.
        /// </summary>
        public void Standby()
        {
            try
            {
                this.Listener.BeginAcceptSocket(this.Callback, null);
            }
            catch { }
        }

        #endregion
    }
}
